﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2010-06-11
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


class FModelConfig;


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct IFModelBone
{
    // 取得骨骼名
    virtual const ACHAR* GetName() = 0;
    // 取得父骨骼索引
    // .return 父骨骼索引，如果没有父骨骼返回eCD_FMD_ErrorBone
    virtual BYTE GetParent() = 0;
    // 取得子骨骼数量
    virtual size_t GetChildCount() = 0;
    // 取得指定子骨骼索引
    // .child_idx 子骨骼索引
    // .return 子骨骼索引，如果没有父骨骼返回eCD_FMD_ErrorBone
    virtual BYTE GetChildIdx(size_t child_idx) = 0;
    // 取得本骨骼的HASH值
    virtual FIDHASH GetHash() = 0;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct IFModelSubset
{
    // 获取子集名称
    virtual const ACHAR* GetName() = 0;
    // 获取子集类型
    virtual WORD GetType() = 0;
    // 获取子集的贴图索引
    virtual BYTE GetTextrueIdx(EF_MATERIAL_TYPE t) = 0;
    // 获取子集的渲染标记
    virtual DWORD GetRenderFlags(EF_MATERIAL_TYPE t) = 0;
    // 获取顶点总数
    virtual size_t GetVertCount() = 0;
    // 获取面总数
    virtual size_t GetFaceCount() = 0;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct IFModelBillboard
{

};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct IFModelParticle
{

};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct IFModelRibbon
{

};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct IFModelLight
{

};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class IFModelFile : public IFFileObject
{
public:
    FIDMODEL nModelID;          // 模型ID

    virtual int GetFrameCount() = 0;
    virtual int GetFrameRate() = 0;
    virtual size_t GetBoneCount() = 0;
    virtual IFModelBone* GetBone(size_t bone_idx) = 0;
    virtual size_t GetSubsetCount() = 0;
    virtual IFModelSubset* GetSubset(size_t sub_idx) = 0;
    virtual size_t GetTexCount() = 0;
    virtual const ACHAR* GetTexFile(size_t tex_idx) = 0;
    virtual size_t GetBillboardCount() = 0;
    virtual size_t GetParticleCount() = 0;
    virtual size_t GetRibbonCount() = 0;
    virtual size_t GetLightCount() = 0;
    virtual size_t GetAppendPointCount() = 0;
    virtual size_t GetCameraCount() = 0;
    virtual FModelConfig* GetConfig() = 0;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class IFModel : public IFService
{
protected:
    explicit IFModel()
        :IFService(0)
    {}

public:
    // 通过指定ID注册一个模型文件（注意：eCD_DefModelID < ID < eCD_AutoModBegin）
    // .filename 模型文件路径（游戏执行程序的相对目录，或者绝对目录）
    // .id 该模型期望的ID号（如果ID=eCD_ErrorTex则自动生成ID，否则返回期望的ID）
    // .return 该模型实际ID，失败返回eCD_ErrorTex
    virtual FIDMODEL Register(const WCHAR* filename, FIDMODEL id = eCD_ErrorModel) = 0;
    virtual FIDMODEL Register(const ACHAR* filename, FIDMODEL id = eCD_ErrorModel) = 0;
    // 使用已经注册的模型ID创建模型
    // .id 已经注册过的ID号
    // .return 该模型的地址，如果失败返回0
    virtual const IFModelFile* const Create(FIDMODEL id) = 0;
    // 通过文件路径创建创建模型
    // .filename 模型文件路径
    // .return 该模型的地址，如果失败返回0
    virtual FIDMODEL Create(const WCHAR* filename) = 0;
    virtual FIDMODEL Create(const ACHAR* filename) = 0;
    // 通过文件缓存创建模型，需要同时指定模型配置内存
    // .fmd_buf,fmd_size 模型文件的内存信息
    // .cfg_buf,cfg_size 模型配置文件内存数据，如果没有可以填0
    virtual FIDMODEL Create(const BYTE* fmd_buf, size_t fmd_size, const BYTE* cfg_buf = 0, size_t cfg_size = 0) = 0;
    // 消毁指定模型
    // .id 被消毁的模型ID
    virtual void Destroy(FIDMODEL id) = 0;
    // 消毁指定模型
    // .id 被消毁的模型ID，，消毁以后并自动将id设为eCD_ErrorModel
    virtual void DestroyEx(FIDMODEL& id) = 0;
    // 取指定模型ID数据（仅能返回正在使用中的）
    virtual const IFModelFile* const GetModelFile(FIDMODEL id) const = 0;
    // 将一个模型设为常用，即永注内存不消毁，直到程序结束
    virtual bool Solidify(FIDMODEL id) = 0;
};